package abel.wlmr.model.unit;

import java.util.ArrayList;
import java.util.List;

import abel.wlmr.model.WlmrBaseUnit;
import abel.wlmr.model.WlmrException;
import abel.wlmr.model.type.AfnType;
import abel.wlmr.model.type.DataIdBody;
import abel.wlmr.model.type.WlmrErrorType;
import io.netty.buffer.ByteBuf;

/**
 * 数据单元标识
 * 数据单元
 * EC（见本附录 B.4.3.4.6.3）
 * Tp（见本附录 B.4.3.4.6.4）
 * 
 * F1 全部确认：对收到报文中的全部数据单元标识进行确认 p0
 * B.5.1.3.1 F1：全部确认
 * 无数据体。
 * 
 * @author Abel
 *
 */
public class Afn00F3Unit extends WlmrBaseUnit {
    private static final short MIN_LENGTH = 1;

    private AfnType confirmingAfn;
    private List<DataIdBody> idList = new ArrayList<>();
    private List<WlmrErrorType> errList = new ArrayList<>();

    /**
     * 
     */
    public Afn00F3Unit() {
        super();
    }

    /**
     * @param guessedLen
     */
    public Afn00F3Unit(short guessedLen) {
        super(guessedLen);
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitPart#appendBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public ByteBuf appendBuf(ByteBuf buf) {
        if (confirmingAfn == null) {
            throw new IllegalArgumentException("confirming afn can't be null");
        }

        if (idList.size() != errList.size()) {
            throw new IllegalArgumentException("unit id & err should be non-empty && corresponsive");
        }

        buf.writeByte(confirmingAfn.getValue());

        for (int i = 0; i < idList.size(); i++) {
            DataIdBody id1 = idList.get(i);
            id1.appendBuf(buf);

            buf.writeByte(errList.get(i).getValue());
        }

        return buf;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitPart#parseBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public int parseBuf(ByteBuf buf) throws WlmrException {
        if (checkBuffer(buf) < 0) {
            return -1;
        }

        int rlen = getGuessedLength() - getMinLength();
        int size = rlen / 5;

        // 1 bytes.
        confirmingAfn = AfnType.findEnumByValue((short) (buf.readByte() & 0xFF));

        // size * (4 + 1) bytes.
        for (int i = 0; i < size; i++) {
            DataIdBody id = new DataIdBody();
            id.parseBuf(buf);
            idList.add(id);

            errList.add(WlmrErrorType.findEnumByValue((short) (0xFF & buf.readByte())));
        }

        return getGuessedLength();
    }

    @Override
    public int getMinLength() {
        return MIN_LENGTH;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getFinalLen()
     */
    @Override
    public short getFinalLen() {
        if (finalLen < 0) {
            finalLen = (short) (MIN_LENGTH + (4 + 1) * idList.size());
        }
        return finalLen;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return String.format("{confirmingAfn:%s, idList:%s, errList:%s}",
            confirmingAfn, idList, errList);
    }

    /**
     * @return the confirmingAfn
     */
    public AfnType getConfirmingAfn() {
        return confirmingAfn;
    }

    /**
     * @param confirmingAfn
     *            the confirmingAfn to set
     */
    public void setConfirmingAfn(AfnType confirmingAfn) {
        this.confirmingAfn = confirmingAfn;
    }

    /**
     * @return the idList
     */
    public List<DataIdBody> getIdList() {
        return idList;
    }

    /**
     * @param idList
     *            the idList to set
     */
    public void setIdList(List<DataIdBody> idList) {
        this.idList = idList;
    }

    /**
     * @return the errList
     */
    public List<WlmrErrorType> getErrList() {
        return errList;
    }

    /**
     * @param errList
     *            the errList to set
     */
    public void setErrList(List<WlmrErrorType> errList) {
        this.errList = errList;
    }

}
